import { DeepReadonly, readonly } from 'vue'

import pagesJson from '../pages.json'

const tabBarPagesMap = pagesJson.pages.map((i) => {
  return {
    type: 'pages',
    name: i.name,
    path: `/${i.path}`
  }
})

const subPagesMap = pagesJson.subPackages.flatMap((i) => {
  return i.pages.map((x) => {
    return {
      type: 'subPage',
      name: x.name,
      path: `/${i.root}/${x.path}`
    }
  })
})

export const pagesMap = [...tabBarPagesMap, ...subPagesMap]

const pages = pagesMap.reduce((obj, item) => ({ ...obj, [item.name]: item.path }), {})

type PageNames = keyof typeof pages

const routeStore = {} as Record<PageNames, unknown>

export function getRouteParams<T extends PageNames>(page: T | any): DeepReadonly<any> {
  const p = routeStore[page] as any
  return readonly(p)
}

let navigateLock = false
function navigate<T extends PageNames>(page: T | any, params?: any): Promise<any> {
  if (navigateLock) return
  const eventName = Math.floor(Math.random() * 1000) + new Date().getTime() // 生成唯一事件名
  navigateLock = true
  routeStore[page] = params
  uni.navigateTo({
    url: `${pages[page]}?eventName=${eventName}`,
    complete() {
      navigateLock = false
    }
  })

  return new Promise<any>(
    (resolve, reject) => (uni.$once(eventName as any, resolve), uni.$once(eventName as any, reject))
  )
}

function redirect<T extends PageNames>(page: T | any, params?: any) {
  routeStore[page] = params
  uni.redirectTo({ url: pages[page] })
}

function reLaunch<T extends PageNames>(page: T | any, params?: any) {
  routeStore[page] = params
  uni.reLaunch({ url: pages[page] })
}

function switchTab<T extends PageNames>(page: T | any, params?: any) {
  routeStore[page] = params
  uni.switchTab({ url: pages[page] })
}

interface BackParams {
  /** 返回页面层级 */
  delta?: number
  /** 返回携带的数据 */
  data?: any
}

function back({ delta, data }: BackParams = { delta: 1, data: null }) {
  const currentRoute = getCurrentPages().pop()
  const eventName = (currentRoute as any).options.eventName
  uni.$emit(eventName, data)
  uni.navigateBack({
    delta
  })
}

const router = {
  navigate,
  redirect,
  reLaunch,
  switchTab,
  back
}

export default router
